package com.beetobe.main;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;

import com.beetobe.callib.CalendarDialogBuilder;
import com.beetobe.callib.CalendarLibHelper;
import com.beetobe.callib.ClientCredentials;
import com.beetobe.callib.calendar.AsyncLoadCalendars;
import com.beetobe.callib.calendar.CalendarInfo;
import com.beetobe.callib.event.AsyncInsertEvent;
import com.beetobe.callib.event.AsyncLoadEvents;
import com.beetobe.main.schedule.CalendarActivity;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.GoogleHeaders;
import com.google.api.client.googleapis.extensions.android.accounts.GoogleAccountManager;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.googleapis.services.GoogleKeyInitializer;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.calendar.model.AclRule;
import com.google.api.services.calendar.model.AclRule.Scope;

/**
 * Sample for Google Calendar API v3. It shows how to authenticate, get =======
 * /*alendar API v3. It shows how to authenticate, get >>>>>>> .r67 calendars,
 * add a new calendar, update it, and delete it.
 * 
 * <p>
 * To enable logging of HTTP requests/responses, change {@link #LOGGING_LEVEL}
 * to {@link Level#CONFIG} or {@link Level#ALL} and run this command:
 * </p>
 * 
 * <pre>
 * adb shell setprop log.tag.HttpTransport DEBUG
 * </pre>
 * 
 * @author Yaniv Inbar
 */

public final class MainActivity extends Activity {

	/** Logging level for HTTP requests/responses. */
	private static final Level LOGGING_LEVEL = Level.OFF;

	private static final String TAG = "MainActivity";

	private static final String AUTH_TOKEN_TYPE = "cl";

	private int FROM_ADDFRIEND = 3;

	private static final int MENU_ACCOUNTS = 0;

	private static final int MENU_ADD = 1;

	private final int INVITE_KAKAO = 2;

	private static final int CONTEXT_EDIT = 0;

	private static final int CONTEXT_DELETE = 1;

	private static final int REQUEST_AUTHENTICATE = 0;

	public com.google.api.services.calendar.Calendar client;

	final HttpTransport transport = AndroidHttp.newCompatibleTransport();

	final JsonFactory jsonFactory = new GsonFactory();

	static final String PREF_ACCOUNT_NAME = "accountName";

	static final String PREF_AUTH_TOKEN = "authToken";

	SharedPreferences settings;

	GoogleAccountManager accountManager;

	String authToken;

	List<CalendarInfo> calendars = CalendarLibHelper.calednars;

	private boolean received401;

	CalendarDialogBuilder calendarDialogBuilder;

	// Activity 占쏙옙占�占신곤옙占쏙옙占쏙옙

	private final int ACT_GET = 0;

	// Calendar ListView 占신곤옙占쏙옙占쏙옙

	private ListView calendarListView;

	private ArrayAdapter calendarListViewAdapter;

	private String encoding = "UTF-8";
	String recvCalID;
	String recvAccName;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		Intent intent = getIntent();
		final String regID = intent.getStringExtra("REG_ID");
		final String calID = intent.getStringExtra("CAL_ID");
		recvCalID = intent.getStringExtra("RECV_CAL_ID");
		recvAccName = intent.getStringExtra("RECV_ACCOUNT_NAME");

		// String nullString = null;
		// if (regID == null)
		// nullString = "NULL";
		// else
		// nullString = regID;

		Toast.makeText(this, regID + ", " + calID, 0).show();

		// pDlg = new ProgressDialog(this);
		if (CalendarLibHelper.calednars != null)
			CalendarLibHelper.calednars.clear();
		if (CalendarLibHelper.selectDay != null)
			CalendarLibHelper.selectDay.clear();
		if (CalendarLibHelper.eventList != null)
			CalendarLibHelper.eventList.clear();
		if (CalendarLibHelper.newCalendarName != null)
			CalendarLibHelper.newCalendarName = null;

		ImageButton addSchedule = (ImageButton) findViewById(R.id.Btn_AddSchedule);
		ImageView title = (ImageView) findViewById(R.id.ImageView_Title);
		ImageButton editSchedule = (ImageButton) findViewById(R.id.Btn_EditSchedule);
		ListView Schedual = (ListView) findViewById(R.id.listView_Calendar);

		editSchedule.setOnClickListener(new Button.OnClickListener() {
			public void onClick(View v) {

				new AsyncSendGCM(regID, calID).execute();
			}

		});

		addSchedule.setOnClickListener(new Button.OnClickListener() {
			public void onClick(View v) {
				// if (accountManager.getAccounts().length >= 2) {
				// // menu.add(0, MENU_ACCOUNTS, 0, "Switch Account");
				// // 占쏙옙占쏙옙占쏙옙 2占쏙옙 占싱삼옙占쏙옙 占쏙옙, 占쏙옙占쏙옙占싫듸옙
				// chooseAccount();
				// }
				calendarDialogBuilder.getCalendarInsertDiglog(
						R.layout.calendar_insert_dialog_layout,
						R.id.editText_calendar_insert,
						R.id.btn_month_calendar_insert,
						R.id.btn_clock_calendar_insert);
			}
		});

		// 占쏙옙占썩서 占쏙옙 占쌘듸옙
		HttpRequestInitializer requestInitializer = new HttpRequestInitializer() {

			public void initialize(HttpRequest request) throws IOException {
				request.getHeaders().setAuthorization(
						GoogleHeaders.getGoogleLoginValue(authToken));
			}
		};

		CalendarLibHelper.client = new com.google.api.services.calendar.Calendar.Builder(
				transport, jsonFactory, requestInitializer)
				.setApplicationName(
				/* "Google-CalendarAndroidSample/1.0" */"Bee To Be")
				.setJsonHttpRequestInitializer(
						new GoogleKeyInitializer(ClientCredentials.KEY))
				.build();

		calendarDialogBuilder = new CalendarDialogBuilder(this);
		settings = getPreferences(MODE_PRIVATE);
		CalendarLibHelper.accountName = settings.getString(PREF_ACCOUNT_NAME,
				null);
		authToken = settings.getString(PREF_AUTH_TOKEN, null);
		Logger.getLogger("com.google.api.client").setLevel(LOGGING_LEVEL);
		accountManager = new GoogleAccountManager(this);

		calendarListView = (ListView) findViewById(R.id.listView_Calendar);
		calendarListViewAdapter = new ArrayAdapter<CalendarInfo>(this,
				android.R.layout.simple_list_item_1, calendars);
		calendarListView.setAdapter(calendarListViewAdapter);

		calendarListView
				.setOnItemClickListener(new AdapterView.OnItemClickListener() {
					public void onItemClick(AdapterView<?> parent, View view,
							int position, long id) {

						// pDlg.setMessage("일정을 가져옵니다.");
						// pDlg.show();
						new AsyncLoadEvents(MainActivity.this, calendars
								.get(position).id).execute();
						CalendarLibHelper.isEventLoaded = false;
						while (!CalendarLibHelper.isEventLoaded) {

						}
						// pDlg.dismiss();

						Intent intent = new Intent(MainActivity.this,
								CalendarActivity.class);
						intent.putExtra("CALENDAR_ID",
								calendars.get(position).id);
						CalendarLibHelper.calendarId = calendars.get(position).id;
						intent.putExtra("MODE", 1);
						startActivity(intent);

						// finish();
					}
				});

		calendarListView
				.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
					public void onCreateContextMenu(ContextMenu menu, View v,
							ContextMenuInfo menuInfo) {
						// menu.add(0, CONTEXT_EDIT, 0, "Edit Title");
						menu.add(0, CONTEXT_DELETE, 0, "모임 지우기");
						menu.add(0, INVITE_KAKAO, 0, "카카오톡으로 초대장 보내기");
					}
				});
		gotAccount();

		if (recvCalID != null && recvAccName != null) {
			Toast.makeText(this, "초대" +
					"" +
					"장을 받았습니다. 초대중입니다.", 0).show();
			CalendarLibHelper.isFriendAdded = false;
			new AsyncAddFriend(this).execute();
			while (!CalendarLibHelper.isFriendAdded) {

			}
			CalendarLibHelper.isEventInserted = false;
			new AsyncInsertEvent(recvCalID, recvAccName, FROM_ADDFRIEND)
					.execute();
			while (!CalendarLibHelper.isEventInserted) {

			}

		}

	}

	// 占쏙옙클占쏙옙占쌔쇽옙 占쏙옙타占쏙옙 占쏙옙占쏙옙占쌜듸옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙占쏙옙
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
				.getMenuInfo();
		int calendarIndex = (int) info.id;
		CalendarInfo calendarInfo = calendars.get(calendarIndex);
		switch (item.getItemId()) {
		// case CONTEXT_EDIT: // update
		// calendarDialogBuilder.getCalendarUpdateDialog(
		// R.layout.calendar_update_dialog_layout,
		// R.id.editText_calendar_update, calendarIndex);
		// return true;
		case CONTEXT_DELETE: // delete
			calendarDialogBuilder.getCalendarDeleteDialog(
					R.layout.calendar_delete_dialog_layout, calendarIndex);
			return true;
		case INVITE_KAKAO:
			KakaoLink kakaoLink = KakaoLink.getLink(getApplicationContext());
			kakaoLink.invite(this, calendarInfo);
			return true;

		default:
			return super.onContextItemSelected(item);
		}
	}

	void gotAccount() {
		// 占싱뱄옙 占쌜곤옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쌜곤옙占쏙옙占쏙옙 占쏙옙占쏙옙占승댐옙. 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占싹듸옙占쏙옙
		// 占싼댐옙.
		Account account = accountManager
				.getAccountByName(CalendarLibHelper.accountName);

		if (account == null || accountManager.getAccounts().length >= 2) {
			chooseAccount(); // 占쏙옙占쏙옙占쏙옙 占쏙옙占쌜곤옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙
								// chooseAccount占쏙옙 占쏙옙占쌔쇽옙 占쏙옙占쏙옙占쏙옙
								// 占쏙옙占쏙옙占싹듸옙占쏙옙 占싼댐옙.
			return;
		}
		if (authToken != null) { // 占싱뱄옙 Token占쏙옙 占쌍억옙占쏙옙 占쏙옙占쏙옙 占쏙옙
			onAuthToken();
			return;
		}

		// AccountManagerCallBack 클占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占� // Google
		// Calendar v3 API占쏙옙 占쏙옙占썽서 占쏙옙占쏙옙.
		// 占쏙옙占쏙옙占쏙옙 占쏙옙占쌜곤옙占쏙옙占쏙옙 占쏙옙占쏙옙占싹곤옙 Token占쏙옙 占쌍억옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙
		// 占싣뤄옙 占쌘듸옙 占쏙옙占쏙옙(token 占쏙옙占�占쌘듸옙)
		class AccountManagerCallBackClass implements
				AccountManagerCallback<Bundle> {

			public void run(AccountManagerFuture<Bundle> future) {
				try {
					Bundle bundle = future.getResult();
					if (bundle.containsKey(AccountManager.KEY_INTENT)) {
						Intent intent = bundle
								.getParcelable(AccountManager.KEY_INTENT);
						intent.setFlags(intent.getFlags()
								& ~Intent.FLAG_ACTIVITY_NEW_TASK);
						startActivityForResult(intent, REQUEST_AUTHENTICATE);
					} else if (bundle.containsKey(AccountManager.KEY_AUTHTOKEN)) {
						setAuthToken(bundle
								.getString(AccountManager.KEY_AUTHTOKEN));
						onAuthToken();
					}
				} catch (Exception e) {
					Log.e(TAG, e.getMessage(), e);
				}
			}
		}
		accountManager.getAccountManager().getAuthToken(account,
				AUTH_TOKEN_TYPE, null, this, new AccountManagerCallBackClass(),
				null);
	}

	// 占싱뱄옙 占쌘듸옙占쏙옙 占쏙옙溝占�占쏙옙占쏙옙 占쌩울옙 占싹놂옙占쏙옙 占쏙옙占쏙옙占싹듸옙占쏙옙 占싼댐옙. 占쏙옙
	// 占쏙옙占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙悶占쏙옙占�占썬가占쏙옙 占쏙옙쨈占�
	private void chooseAccount() {
		accountManager.getAccountManager().getAuthTokenByFeatures(
				GoogleAccountManager.ACCOUNT_TYPE, AUTH_TOKEN_TYPE, null,
				MainActivity.this, null, null,
				new AccountManagerCallback<Bundle>() {

					public void run(AccountManagerFuture<Bundle> future) {
						Bundle bundle;
						try {
							bundle = future.getResult();
							setAccountName(bundle
									.getString(AccountManager.KEY_ACCOUNT_NAME));
							setAuthToken(bundle
									.getString(AccountManager.KEY_AUTHTOKEN));
							onAuthToken(); // AsyncLoadCalendars
						} catch (OperationCanceledException e) {
							// user canceled
						} catch (AuthenticatorException e) {
							Log.e(TAG, e.getMessage(), e);
						} catch (IOException e) {
							Log.e(TAG, e.getMessage(), e);
						}
					}
				}, null);
	}

	// 占쏙옙占쏙옙占쏙옙 占싱몌옙占쏙옙 占쏙옙占쏙옙占싼댐옙.
	void setAccountName(String accountName) {
		SharedPreferences.Editor editor = settings.edit();
		editor.putString(PREF_ACCOUNT_NAME, accountName);
		editor.commit();
		CalendarLibHelper.accountName = accountName;
	}

	// 占쏙옙占쏙옙占쏙옙 Auth占쏙옙 Token占쏙옙 占쏙옙占쏙옙占싼댐옙.
	void setAuthToken(String authToken) {
		SharedPreferences.Editor editor = settings.edit();
		editor.putString(PREF_AUTH_TOKEN, authToken);
		editor.commit();
		this.authToken = authToken;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		switch (requestCode) {
		case REQUEST_AUTHENTICATE:
			if (resultCode == RESULT_OK) {
				gotAccount();
			} else {
				chooseAccount();
			}
			break;
		}
	}

	// 占쌨댐옙 占쏙옙튼 占쏙옙占쏙옙占쏙옙占쏙옙 占쌨쇽옙占쏙옙
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		return false;
	}

	// 占쌨댐옙 占쏙옙占쏙옙트 占쏙옙 占싹놂옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙 占쏙옙 占쌨쇽옙占쏙옙
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		}
		return false;
	}

	// 占쏙옙-클占쏙옙占쏙옙占쏙옙占쏙옙 占쏙옙타占쏙옙占쏙옙 占쌨댐옙占쏙옙占쏙옙

	// gotAccount占쏙옙占쏙옙 占쏙옙占싱댐옙 占쌨쇽옙占쏙옙. 占싱뱄옙 AuthToken占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙,
	// 占싣뤄옙占쏙옙 클占쏙옙占쏙옙占쏙옙 占싱울옙占쏙옙 占쏙옙占쏙옙占쏙옙 캘占쏙옙占쏙옙占쏙옙
	// 占싸듸옙占쌔온댐옙.
	void onAuthToken() {

		// calendarListView.removeAllViews();
		new AsyncLoadCalendars(this).execute();

		this.onResume();
		// AsyncLoadCalendars클래스는 오직 캘린더 리스트를 로드해오는데 쓰인다.

		// 占쏙옙占쏙옙占쏙옙占�占쌈쏙옙
		// Intent intent = new Intent(MainActivity.this,
		// EventListActivity.class);
		// intent.putExtra("CALENDAR_ID", 0);
		// startActivityForResult(intent, ACT_GET);
		// 占쏙옙占쏙옙占쏙옙占�占쏙옙占쏙옙占쏙옙占쏙옙.
	}

	// 占쏙옙占쏙옙, 占쏙옙占쏙옙, 占싸듸옙, 占쏙옙占쏙옙占쏙옙트 클占쏙옙占쏙옙占쏙옙占쏙옙 占쏙옙占싫댐옙. 占쏙옙占쏙옙占쏙옙占쏙옙占쏙옙
	// 占쏙옙占�처占쏙옙占실몌옙 received401占쏙옙 false占쏙옙 占쌕꾼댐옙.
	public void onRequestCompleted() {
		received401 = false;
	}

	// 占쏙옙占쏙옙처占쏙옙 占쌨쇽옙占쏙옙
	public void handleGoogleException(final IOException e) {
		if (e instanceof GoogleJsonResponseException) {
			GoogleJsonResponseException exception = (GoogleJsonResponseException) e;
			if (exception.getStatusCode() == 401 && !received401) {
				received401 = true;
				accountManager.invalidateAuthToken(authToken);
				authToken = null;
				SharedPreferences.Editor editor2 = settings.edit();
				editor2.remove(PREF_AUTH_TOKEN);
				editor2.commit();
				gotAccount();
			}
		}
		Log.e(TAG, e.getMessage(), e);
		runOnUiThread(new Runnable() {
			public void run() {
				new AlertDialog.Builder(MainActivity.this)
						.setTitle("Exception").setMessage(e.getMessage())
						.setNeutralButton("ok", null).create().show();
			}
		});
	}

	// 占쏙옙占쏙옙, 占쏙옙占쏙옙, 占싸듸옙, 占쏙옙占쏙옙占쏙옙트 占식울옙 占쌕시깍옙 화占쏙옙占쏙옙 占쏙옙占쏙옙求쨉占�占쏙옙占싸댐옙.
	public void refresh() {
		// Collections.sort(calendars);
		calendarListViewAdapter.notifyDataSetChanged();
	}

	@Override
	public void onResume() {
		calendarListViewAdapter.notifyDataSetChanged();
		super.onResume();
	}

}
